/*
 * MoveBetamon.java
 *
 * Created on November 14, 2007, 3:17 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package hotgammon.domain;

/**
 *
 * @author nick
 */
public class MoveBetamon implements Move{
    private Board board;
    private Game game;
    
    /**
     * Creates a new instance of MoveBetamon
     */
    public MoveBetamon(Board board) {
        this.board = board;
    }
    
    public void setGame(Game game) {
        this.game = game;
    }
    
    /** Move one checker from one location to another.
     * @param from the location to move the stone from
     * @param to the location to move the stone to
     * @return false if the indicated move is illegal
     */
    public boolean move(Location from, Location to) {
        int length = Location.distance(from, to);
        int absLength = Math.abs(length);
        int[] diceValues = game.diceValuesLeft();
        Color colorTo = board.getColor(to);
        Color colorFrom = board.getColor(from);
        Color playerInTurn = game.getPlayerInTurn();
        int countTo = board.getCount(to);       
        
        // Check that current player's bar is empty'
        if ( (playerInTurn == Color.RED && board.getCount(Location.R_BAR) == 0 && from != Location.R_BAR) ||
                (playerInTurn == Color.BLACK && board.getCount(Location.B_BAR) == 0) && from != Location.B_BAR ) {
            
            // Move directly to a bar is illegal
            if(to == Location.R_BAR || to == Location.B_BAR) return false;
            
            // Check dice values against distance of move
            if(absLength != diceValues[0] && absLength != diceValues[1]) return false;
            
            // Correct color of checker
            if(colorFrom != playerInTurn) return false;
            
            // Not legal to move to a location with 2 or move ememy checkers
            if(colorTo != playerInTurn && colorTo != Color.NONE && countTo > 1) return false;
            
            // Red cannot move clockwise
            if(playerInTurn == Color.RED && length > 0) return false;
            
            // Black cannot move counter clockwise
            if(playerInTurn == Color.BLACK && length < 0) return false;
            
            // Check that out from bar is legal
        } else {
            
            // Current player has a checker on the bar and has to move it first
            if ( (playerInTurn != Color.RED && from != Location.B_BAR) ||
                    (playerInTurn != Color.BLACK && from != Location.R_BAR) ) return false;
            
            // Move directly to a bar is illegal
            if(to == Location.R_BAR || to == Location.B_BAR) return false;
            
            // Check dice values against distance of move
            if(absLength != diceValues[0] && absLength != diceValues[1]) return false;
            
            // Correct color of checker
            if(colorFrom != playerInTurn) return false;
            
            // Not legal to move to a location with 2 or move ememy checkers
            if(colorTo != playerInTurn && colorTo != Color.NONE && countTo > 1) return false;
            
            // Red cannot move clockwise
            if(playerInTurn == Color.RED && length > 0) return false;
            
            // Black cannot move counter clockwise
            if(playerInTurn == Color.BLACK && length < 0) return false;
            
        }
        
        // Send ememy checker to bar
        if(countTo == 1 && colorTo != playerInTurn && playerInTurn == Color.BLACK) {
            board.move(to, Location.R_BAR);
        }
        if(countTo == 1 && colorTo != playerInTurn && playerInTurn == Color.RED) {
            board.move(to, Location.B_BAR);
        }
        
        // The move is legal
        board.move(from, to);
        
        // Set the proper value in the dice array
//        if(absLength == diceValues[0]) diceValues[0] = 0;
//        else diceValues[1] = 0;
            
        boolean hasDeleted = false;
        for (int n = diceValues.length-1; n>=0 && !hasDeleted; n--) {
            if (diceValues[n]==absLength) {
                game.getDice().getValuesLeft()[n] = 0;
                hasDeleted=true;
            }
        }
        if (!hasDeleted) return false;
        
        // Signal naxt turn if the player doesn't have any moves left'
        if(game.getNumberOfMovesLeft() == 0) {
            game.nextTurn();
        }
        
        return true;
    }
    
    public static void reverse(int[] b) {
        int left  = 0;          // index of leftmost element
        int right = b.length-1; // index of rightmost element
        
        while (left < right) {
            // exchange the left and right elements
            int temp = b[left];
            b[left]  = b[right];
            b[right] = temp;
            
            // move the bounds toward the center
            left++;
            right--;
        }
    }
}
